package jmine.tec.rpc.server.representation.representers.lazy;

import java.beans.PropertyDescriptor;
import java.util.LinkedHashMap;
import java.util.Map;

import jmine.tec.rpc.server.representation.RepresentationContext;
import jmine.tec.rpc.server.representation.representers.reflection.MapPropertyRepresenter;
import jmine.tec.rpc.server.representation.representers.reflection.RepresenterUtil;
import bancosys.tec.persist.Persistable;

/**
 * Representador lazy de listas
 * 
 * @author lundberg
 * @param <R> tipo de representação
 * @param <E> tipo de entidade representada
 */
public class LazyMapPropertyRepresenter<R, E> extends MapPropertyRepresenter<R, E> {

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean isApplicableTo(PropertyDescriptor representationProperty) {
        return super.isApplicableTo(representationProperty) && RepresenterUtil.isLazy(representationProperty);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected Map<?, ?> createRepresentation(RepresentationContext context, Class<?> keyType, Class<?> valueType, Map<?, ?> map) {
        Map<Object, Object> lazies = new LinkedHashMap<Object, Object>();
        context.register(map, lazies);
        for (Map.Entry<?, ?> e : map.entrySet()) {
            if (this.isLazyable(e.getValue())) {
                lazies.put(e.getKey(), new LazyPersistableBean((Persistable) e.getValue()));
            } else {
                lazies.put(e.getKey(), e.getValue());
            }
        }
        return context.representObjects(keyType, valueType, lazies);
    }

    /**
     * Verifica se o objeto pode ser representado de forma lazy
     * 
     * @param object object
     * @return boolean
     */
    private boolean isLazyable(Object object) {
        return object instanceof Persistable;
    }
}
